/*
 * ClipHelper.java
 *
 * Created on August 28, 2007, 11:29 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package passhashr;
import java.io.IOException;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;

public class ClipHelper
{
	/**
	 * The global Clipboard object that we use for all of
	 * our calls -- it's static so it only has to get created
	 * once, and can then be reused
	 */
	private static Clipboard clipboard = null;
	
	/**
	 * The sole constructor for the ClipHelper class. It does
	 * nothing, because the system Clipboard is retrieved upon
	 * the first call to one of the copy or paste methods (so
	 * there is no overhead associated with creating an instance
	 * of this class if you never use any of the methods).
	 */
	public ClipHelper ()
	{
	}
	
	/**
	 * The private getClipboard method attempts to populate the
	 * local clipboard variable with the system clipboard, if the
	 * variable is currently null (if it's already been assigned
	 * as the system clipboard, there's no need to assign it again).
	 * The trick here is to get the system clipboard reference in
	 * a daemon thread, so the AWT threads created by the call to
	 * Toolkit.getDefaultToolkit() can be killed without the need
	 * to call System.exit().
	 */
	private static void getClipboard ()
	{
		// this is our simple thread that grabs the clipboard
		Thread clipThread = new Thread() {
			public void run() {
				clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
			}
		};
		
		// start the thread as a daemon thread and wait for it to die
		if (clipboard == null) {
			try {
				clipThread.setDaemon(true);
				clipThread.start();
				clipThread.join();
			} catch (Exception e) {
			}
		}
	}
	
	/**
	 * Copies a String to the system clipboard
	 *
	 * @param data    the String to send to the clipboard
	 */
	public static void copyString (String data)
	{
		copyTransferableObject(new StringSelection(data));
	}
	
	/**
	 * Copies a Transferable object to the system clipboard
	 *
	 * @param contents    the item to send to the clipboard, 
	 *                    which must be an object of a class
	 *                    that implements java.awt.datatransfer.Transferable
	 */
	public static void copyTransferableObject (Transferable contents)
	{
		getClipboard();
		clipboard.setContents(contents, null);
	}
	
	/**
	 * Gets a String from the system clipboard (if the object on the
	 * clipboard does not have a String representation, or the clipboard
	 * is empty, this method returns null)
	 *
	 * @return    a String representation of the object on the system
	 *            clipboard, or null if the object doesn't have a String
	 *            representation or the clipboard is empty.
	 */
	public static String pasteString ()
	{
		String data = null;
		try {
			data = (String)pasteObject(DataFlavor.stringFlavor);
		} catch (Exception e) {
			System.err.println("Error getting String from clipboard: " + e);
		}
		
		return data;
	}
	
	/**
	 * Gets an Object from the system clipboard, using the specified 
	 * DataFlavor format. This method throws any exceptions that are
	 * thrown by the Transferable.getTransferData() method (UnsupportedFlavorException
	 * if the DataFlavor is not supported, IOException if the data is
	 * not available in the requested flavor).
	 *
	 * @return    an Object of the class defined by the DataFlavor
	 *            that was requested, or null if the clipboard is empty
	 * @exception IOException    if the clipboard data is no longer available 
	 *                           in the requested flavor
	 * @exception UnsupportedFlavorException    if the requested data flavor 
	 *                                          is not supported
	 */
	public static Object pasteObject (DataFlavor flavor) 
			throws UnsupportedFlavorException, IOException
	{
		Object obj = null;
		getClipboard();
		
		Transferable content = clipboard.getContents(null);
		if (content != null)
			obj = content.getTransferData(flavor);
		
		return obj;
	}
	
}